package com.khalil.kkadmin.system.dms;

import com.alibaba.fastjson2.JSON;
import com.khalil.kkadmin.common.util.JsonUtil;
import com.khalil.kkadmin.infrastructure.BaseService;
import com.khalil.kkadmin.infrastructure.properties.DmsProperties;
import com.khalil.kkadmin.system.dms.store.DocumentStore;
import com.khalil.kkadmin.system.dms.store.DocumentStoreFactory;
import com.khalil.kkadmin.system.dms.store.DocumentStoreInfo;
import com.khalil.kkadmin.system.dms.store.StoreType;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class DmsDocumentServiceImpl extends BaseService<DmsDocumentRepository, DmsDocument, Long> implements DmsDocumentService {

    private final DocumentStoreFactory documentStoreFactory;

    @Autowired
    private DmsProperties dmsProperties;

    public DmsDocumentServiceImpl(DmsDocumentRepository repository, DocumentStoreFactory documentStoreFactory) {
        super(repository);
        this.documentStoreFactory = documentStoreFactory;
    }

    @Override
    protected DmsDocument str2CreateEntity(String json) {
        return null;
    }

    @Override
    protected DmsDocument str2UpdateEntity(String json) {
        return null;
    }

    @Override
    public List<DmsDocument> list(String params) {
        return List.of();
    }

    @Override
    public List<DmsDocument> findByIdList(List<Long> idList) {
        return repository.findByIdIn(idList);
    }

    @Transactional
    @Override
    public void deleteById(Long id) {
        DmsDocument dmsDocument = repository.findById(id).orElseThrow();
        StoreType storeType = dmsDocument.getStoreType();
        DocumentStore documentStore = documentStoreFactory.getDocumentStore(storeType);
        String path = dmsDocument.getPath();
        List<String> pathList = JSON.parseArray(path, String.class);
        documentStore.delete(pathList, dmsDocument.getName());
        // 删除数据库记录
        repository.deleteById(id);
    }

    @Override
    public DmsDocument upload(FileInfo fileInfo) {
        return upload(List.of("Other"), fileInfo);
    }

    @Override
    public DmsDocument upload(List<String> pathArr, FileInfo fileInfo) {
        return upload(StoreType.SYSTEM_FILE, pathArr, fileInfo);
    }

    @Override
    public DmsDocument upload(StoreType storeType, List<String> pathArr, FileInfo fileInfo) {
        DmsDocument dmsDocument = new DmsDocument();
        String originalFilename = fileInfo.getOriginalFilename();
        long suffix = System.currentTimeMillis();
        String newFilename = FilenameUtils.getBaseName(originalFilename) + "_" + suffix + "." + fileInfo.getExtension();
        dmsDocument.setName(newFilename);
        dmsDocument.setExtension(fileInfo.getExtension());
        dmsDocument.setContentType(fileInfo.getContentType());
        dmsDocument.setSize(fileInfo.getSize());
        dmsDocument.setPath(JsonUtil.toJsonStr(pathArr));
        dmsDocument.setStoreType(storeType);

        DocumentStoreInfo documentStoreInfo = DocumentStoreInfo.builder().filename(newFilename).pathArr(pathArr).inputStream(fileInfo.getInputStream()).build();

        DocumentStore documentStore = documentStoreFactory.getDocumentStore(storeType);
        documentStore.store(documentStoreInfo);
        return repository.save(dmsDocument);
    }

    @Override
    public FileInfo download(Long id) {
        DmsDocument dmsDocument = repository.findById(id).orElseThrow();
        String path = dmsDocument.getPath();
        List<String> list = JsonUtil.parseJson2List(path, String.class);
        DocumentStore documentStore = documentStoreFactory.getDocumentStore(dmsDocument.getStoreType());
        DocumentStoreInfo documentStoreInfo = documentStore.getDocumentStoreInfo(list, dmsDocument.getName());

        return FileInfo.builder().originalFilename(dmsDocument.getName())
                .extension(dmsDocument.getExtension())
                .contentType(dmsDocument.getContentType())
                .size(dmsDocument.getSize())
                .inputStream(documentStoreInfo.getInputStream())
                .build();
    }
}
